package com.ironone.streaming.mediaplayer;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.media.AudioManager.OnAudioFocusChangeListener;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.ConnectivityManager;
import android.os.IBinder;
import android.os.PowerManager;
import android.support.v4.app.NotificationCompat;
import com.ironone.streaming.R;
import com.ironone.streaming.RadioPlayerActivity;
import com.ironone.streaming.application.FormObject;
import com.ironone.streaming.application.MainApplication;

public class MyMediaPlayerService extends Service {
	public static MediaPlayer mediaPlayer;
	BroadcastReceiver br_ConnectivityCheck;
	BroadcastReceiver br_HeadsetCheck;
	BroadcastReceiver br_commonReceiver;
	NotificationManager mNotificationManager;
	boolean isError = false;
	int isError_ErrorCode = 0;
	static int notifyNum = 0;

	
	@Override
	public void onCreate() {
		try {
			super.onCreate();
			mediaPlayer = MyMediaPlayer.getMediaPlayerInstance();
			mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);

			myMediaPlayerActivityCallbacks();

			getMediaPlayerAudioFocus(getApplicationContext());

			br_ConnectivityCheck = new BroadcastReceiver(){
				@Override
				public void onReceive(Context context, Intent intent) {
					boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
					if (noConnectivity) {
						if(MyMediaPlayer.getMediaPlayerPauseClicked())
							return;

						try {
							MyMediaPlayer.resetAndPrepareMediaPlayer();
						} catch (Exception e) {
							MyMediaPlayer.releaseMediaPlayer();
							Intent intent1 = new Intent(MyMediaPlayer.ACT_NOTIFICATION);
							intent1.putExtra(MyMediaPlayer.VALUE, MyMediaPlayerActivityNotifyStatus.ON_ERROR.ordinal());
							context.sendBroadcast(intent1);
						}

						if (!MyMediaPlayer.getIsPlayerOnBackground()) {  // Player on top of screen
							Intent intent1 = new Intent(MyMediaPlayer.ACT_NOTIFICATION);
							intent1.putExtra(MyMediaPlayer.VALUE, MyMediaPlayerActivityNotifyStatus.CONNECTIVITY.ordinal()); // value == 0
							sendBroadcast(intent1);
						}
					} else{
						//TODO: put a connection available toast if wants
					}
				}
			};
			registerReceiver(br_ConnectivityCheck, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));

			br_HeadsetCheck = new BroadcastReceiver(){
				@Override
				public void onReceive(Context context, Intent intent) {
					int state = intent.getIntExtra("state", 0);
					switch (state) {
					case 0: // Head-set is unplugged / unmounted			
						if (MyMediaPlayer.getIsPlayerOnBackground()) {  // Player NOT on top of screen
							MyMediaPlayer.pauseMediaPlayer();
						} else {
							MyMediaPlayer.pauseMediaPlayer();
							Intent intent2 = new Intent(MyMediaPlayer.ACT_NOTIFICATION);
							intent2.putExtra(MyMediaPlayer.VALUE, MyMediaPlayerActivityNotifyStatus.HEADSET_UNMOUNTED.ordinal()); // value == 1
							sendBroadcast(intent2);
						}
						break;
					case 1: // Head-set is plugged
						break;
					default:
					}
				}
			};
			registerReceiver(br_HeadsetCheck, new IntentFilter(Intent.ACTION_HEADSET_PLUG));

			mediaPlayer.setOnPreparedListener(new OnPreparedListener() {

				public void onPrepared(MediaPlayer mp) {
					try {
						if(MyMediaPlayer.getMediaPlayerPauseClicked()) return;

						if (MyMediaPlayer.getIsPlayerOnBackground()) { // Player NOT on top of screen
							if(MyMediaPlayer.getMediaPlayerStatus() != MediaPlayerStatus.FORCE_PAUSED){
								MyMediaPlayer.playMediaPlayer();						
							}
						} else {
							MyMediaPlayer.playMediaPlayer();

							Intent intent1 = new Intent(MyMediaPlayer.ACT_NOTIFICATION);
							intent1.putExtra(MyMediaPlayer.VALUE, MyMediaPlayerActivityNotifyStatus.ON_PREPARED.ordinal()); // value == 3
							sendBroadcast(intent1);
						}
					}catch (Exception e) {
					}
				}
			});

			mediaPlayer.setOnCompletionListener(new OnCompletionListener() {

				@Override
				public void onCompletion(MediaPlayer arg0) {

					if(isError){
						MyMediaPlayer.resetMediaPlayer();
					}else {
						try {
							MyMediaPlayer.resetAndPrepareMediaPlayer();
						} catch (Exception e) {
							MyMediaPlayer.releaseMediaPlayer();
							Intent intent1 = new Intent(MyMediaPlayer.ACT_NOTIFICATION);
							intent1.putExtra(MyMediaPlayer.VALUE, MyMediaPlayerActivityNotifyStatus.ON_ERROR.ordinal());
							sendBroadcast(intent1);
						}
					}

					if (!MyMediaPlayer.getIsPlayerOnBackground()) { // Player on top of screen
						Intent intent1 = new Intent(MyMediaPlayer.ACT_NOTIFICATION);
						intent1.putExtra(MyMediaPlayer.VALUE, MyMediaPlayerActivityNotifyStatus.ON_COMPLETION.ordinal()); // value == 5
						intent1.putExtra("isError", isError);
						intent1.putExtra("isError_ErrorCode", isError_ErrorCode);
						sendBroadcast(intent1);
					}
				}
			});

			mediaPlayer.setOnBufferingUpdateListener(new OnBufferingUpdateListener() {

				@Override
				public void onBufferingUpdate(MediaPlayer arg0, int percent) {

					if (percent == 100) {
						try {
							MyMediaPlayer.resetAndPrepareMediaPlayer();
						} catch (Exception e) {
							MyMediaPlayer.releaseMediaPlayer();
							Intent intent1 = new Intent(MyMediaPlayer.ACT_NOTIFICATION);
							intent1.putExtra(MyMediaPlayer.VALUE, MyMediaPlayerActivityNotifyStatus.ON_ERROR.ordinal());
							sendBroadcast(intent1);
						}
					}

					if (!MyMediaPlayer.getIsPlayerOnBackground()) {
						Intent intent1 = new Intent(MyMediaPlayer.ACT_NOTIFICATION);
						intent1.putExtra(MyMediaPlayer.VALUE, MyMediaPlayerActivityNotifyStatus.ON_BUFFERING_UPDATE.ordinal()); // value == 6
						intent1.putExtra("percent", percent);
						sendBroadcast(intent1);
					}
				}
			});

			/*mediaPlayer.setOnInfoListener(new OnInfoListener() {

				@Override
				public boolean onInfo(MediaPlayer mp, int what, int extra) {

					if (MyMediaPlayer.getIsPlayerOnBackground()) { // Player NOT on top of screen
					}else {
						Intent intent7 = new Intent(MyMediaPlayer.ACT_NOTIFICATION);
						intent7.putExtra(MyMediaPlayer.VALUE, MyMediaPlayerActivityNotifyStatus.ON_INFO.ordinal()); // value == 7
						intent7.putExtra("what", what);
						sendBroadcast(intent7);
					}
					return false;
				}
			});*/

			mediaPlayer.setOnErrorListener(new OnErrorListener() {

				@Override
				public boolean onError(MediaPlayer mp, int what, int extra) {
					isError = true;
					isError_ErrorCode = extra;
					return false;
				}
			});

		} catch (Exception e) {
			MyMediaPlayer.releaseMediaPlayer();
			Intent intent1 = new Intent(MyMediaPlayer.ACT_NOTIFICATION);
			intent1.putExtra(MyMediaPlayer.VALUE, MyMediaPlayerActivityNotifyStatus.ON_ERROR.ordinal());
			sendBroadcast(intent1);
		}
	}

	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onDestroy() {
		try {
			super.onDestroy();
			unregisterReceiver(br_ConnectivityCheck);
			unregisterReceiver(br_HeadsetCheck);
			unregisterReceiver(br_commonReceiver);
		} catch (Exception e) {
		}
	}

	private static void getMediaPlayerAudioFocus(final Context context) {
		try {
			AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
			audioManager.requestAudioFocus(new OnAudioFocusChangeListener() {

				@Override
				public void onAudioFocusChange(int focusChange) {
					switch (focusChange) {
					case AudioManager.AUDIOFOCUS_GAIN:
						// Resume play-back
						if (MyMediaPlayer.getIsPlayerOnBackground()){
							if(MyMediaPlayer.getMediaPlayerStatus() == MediaPlayerStatus.RELEASED || 
									MyMediaPlayer.getMediaPlayerStatus() == MediaPlayerStatus.RESETED){
								if(!MyMediaPlayer.getMediaPlayerPauseClicked()){
									try {
										MyMediaPlayer.prepareMediaPlayer();
									} catch (Exception e) {
										MyMediaPlayer.releaseMediaPlayer();
										Intent intent1 = new Intent(MyMediaPlayer.ACT_NOTIFICATION);
										intent1.putExtra(MyMediaPlayer.VALUE, MyMediaPlayerActivityNotifyStatus.ON_ERROR.ordinal());
										context.sendBroadcast(intent1);
									}

									//Special case so resume function on plater activity update the UI accordingly
									MyMediaPlayer.setMediaPlayerStatus(MediaPlayerStatus.PREPARING);									
								}
							}else if (MyMediaPlayer.getMediaPlayerStatus() == MediaPlayerStatus.PAUSED){
								MyMediaPlayer.playMediaPlayer();
							}
						}else {
							if(MyMediaPlayer.getMediaPlayerStatus() == MediaPlayerStatus.RELEASED || 
									MyMediaPlayer.getMediaPlayerStatus() == MediaPlayerStatus.RESETED){
								if(!MyMediaPlayer.getMediaPlayerPauseClicked()){
									try {
										MyMediaPlayer.prepareMediaPlayer();
									} catch (Exception e) {
										MyMediaPlayer.releaseMediaPlayer();
										Intent intent1 = new Intent(MyMediaPlayer.ACT_NOTIFICATION);
										intent1.putExtra(MyMediaPlayer.VALUE, MyMediaPlayerActivityNotifyStatus.ON_ERROR.ordinal());
										context.sendBroadcast(intent1);
									}

									//Special case so resume function on plater activity update the UI accordingly
									MyMediaPlayer.setMediaPlayerStatus(MediaPlayerStatus.PREPARING);
								}

								Intent intent3 = new Intent(MyMediaPlayer.ACT_NOTIFICATION);
								intent3.putExtra(MyMediaPlayer.VALUE, MyMediaPlayerActivityNotifyStatus.PREPARE_PLAYER.ordinal()); // value == 3
								context.sendBroadcast(intent3);								
							}else if (MyMediaPlayer.getMediaPlayerStatus() == MediaPlayerStatus.PAUSED){
								MyMediaPlayer.playMediaPlayer();
							}
						}
						MyMediaPlayer.getMediaPlayerInstance().setVolume(1.0f, 1.0f);
						break;

					case AudioManager.AUDIOFOCUS_LOSS:
						// Lost focus for an unbounded amount of time: stop play back and release media player
						if (MyMediaPlayer.getMediaPlayerInstance().isPlaying() || MyMediaPlayer.getMediaPlayerStatus() == MediaPlayerStatus.PLAYING){
							//MyMediaPlayer.releaseMediaPlayer();

							if (MyMediaPlayer.getIsPlayerOnBackground()){
								MyMediaPlayer.releaseMediaPlayer();
							}else {
								MyMediaPlayer.releaseMediaPlayer();

								Intent intent3 = new Intent(MyMediaPlayer.ACT_NOTIFICATION);
								intent3.putExtra(MyMediaPlayer.VALUE, MyMediaPlayerActivityNotifyStatus.AUDIO_FOCUS_LOST.ordinal()); // value == 3
								context.sendBroadcast(intent3);
							}
						}
						break;

					case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
						// Lost focus for a short time, but we have to stop
						// playback. We don't release the media player because playback
						// is likely to resume
						if (MyMediaPlayer.getMediaPlayerInstance().isPlaying() || MyMediaPlayer.getMediaPlayerStatus() == MediaPlayerStatus.PLAYING){

							if (MyMediaPlayer.getIsPlayerOnBackground()){
								MyMediaPlayer.pauseMediaPlayer();
							}else{
								MyMediaPlayer.pauseMediaPlayer();

								Intent intent3 = new Intent(MyMediaPlayer.ACT_NOTIFICATION);
								intent3.putExtra(MyMediaPlayer.VALUE, MyMediaPlayerActivityNotifyStatus.AUDIOFOCUS_LOSS_TRANSIENT.ordinal()); // value == 3
								context.sendBroadcast(intent3);
							}
						}
						break;

					case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
						// Lost focus for a short time, but it's ok to keep playing
						// at an attenuated level
						if (MyMediaPlayer.getMediaPlayerInstance().isPlaying() || MyMediaPlayer.getMediaPlayerStatus() == MediaPlayerStatus.PLAYING)
							MyMediaPlayer.getMediaPlayerInstance().setVolume(0.1f, 0.1f);
						break;
					}
				}
			}, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
		} catch (Exception e) {
			MyMediaPlayer.releaseMediaPlayer();
			Intent intent1 = new Intent(MyMediaPlayer.ACT_NOTIFICATION);
			intent1.putExtra(MyMediaPlayer.VALUE, MyMediaPlayerActivityNotifyStatus.ON_ERROR.ordinal());
			context.sendBroadcast(intent1);
		}
	}

	private void startNotificationOnStatusBar() {
		try {
			// Suren: Custom Notification Attempt (Half way through)
			/*RemoteViews remoteViews = new RemoteViews(this.getPackageName(), R.layout.notification);
			Intent buttonsIntent = new Intent(this, NotifyActivityHandler.class);
			buttonsIntent.putExtra("do_action", "play");
			remoteViews.setOnClickPendingIntent(R.id.playBtn, PendingIntent.getActivity(this, 0, buttonsIntent, 0));
			remoteViews.setTextViewText(R.id.songname_text, "songX name");
			remoteViews.setTextViewText(R.id.artist_text, "artistX name");

			Bitmap icon = MainApplication.getByteArrToBitmap(FormObject.getInstance().getAlbumArtImage());
			if(icon == null)
				icon = BitmapFactory.decodeResource(this.getResources(), R.drawable.icon);

			remoteViews.setImageViewBitmap(R.id.playBtn, icon);

			NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
			.setSmallIcon(R.drawable.icon_small).setContent(remoteViews)
			.setAutoCancel(false);

			// Creates an explicit intent for an Activity in your app  
			//Intent resultIntent = new Intent(this, NotifyActivityHandler.class);  
			// The stack builder object will contain an artificial back stack for  
			// the  
			// started Activity.
			// This ensures that navigating backward from the Activity leads out of  
			// your application to the Home screen.  
			TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);  
			// Adds the back stack for the Intent (but not the Intent itself)  
			stackBuilder.addParentStack(NotifyActivityHandler.class);
			// Adds the Intent that starts the Activity to the top of the stack  
			stackBuilder.addNextIntent(buttonsIntent);  
			PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);  
			remoteViews.setOnClickPendingIntent(R.id.playBtn, resultPendingIntent);  
			NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);  
			// mId allows you to update the notification later on.  
			mNotificationManager.notify(0, mBuilder.build());*/
						
			Intent notificationIntent = new Intent(this, RadioPlayerActivity.class);
			notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
			PendingIntent intent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
			
			NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
			mBuilder.setSmallIcon(R.drawable.icon_small);
			mBuilder.setPriority(2);
			mBuilder.setAutoCancel(true);
			mBuilder.setTicker(getString(R.string.app_name));
			
			Bitmap icon = null;
			if(MyMediaPlayer.isPlaying()){
				icon = MainApplication.getByteArrToBitmap(FormObject.getInstance().getAlbumArtImage());
				if(icon == null) icon = BitmapFactory.decodeResource(this.getResources(), R.drawable.albumart_default_small);
				
				mBuilder.setContentTitle(FormObject.getInstance().getSongName());
				mBuilder.setContentText(FormObject.getInstance().getArtistName());
				
				if(FormObject.getInstance().getSongName().equals("")){
					mBuilder.setContentTitle(getString(R.string.app_name));
					mBuilder.setContentText(getString(R.string.notification_sec_text));
				}
				if(FormObject.getInstance().getArtistName().equals("")){
					mBuilder.setContentText(getString(R.string.app_name));
				}
				if(FormObject.getInstance().getArtistName().equals("") && FormObject.getInstance().getArtistName().equals("")){
					mBuilder.setContentTitle(getString(R.string.app_name));
					mBuilder.setContentText(getString(R.string.notification_sec_text));
				}
			}else {
				icon = BitmapFactory.decodeResource(this.getResources(), R.drawable.albumart_default_small);
				mBuilder.setContentTitle(getString(R.string.app_name));
				mBuilder.setContentText(getString(R.string.notification_sec_text));
			}
			mBuilder.setLargeIcon(icon);
			mBuilder.setContentIntent(intent);
			

			
			/* Add Big View Specific Configuration */
			NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
			String[] events = new String[2];
			
			if(MyMediaPlayer.isPlaying()){								
				inboxStyle.setBigContentTitle(FormObject.getInstance().getSongName());
				events[0] = new String(FormObject.getInstance().getArtistName());
				events[1] = new String(getString(R.string.app_name));
				
				if(FormObject.getInstance().getSongName().equals("")){
					inboxStyle.setBigContentTitle(getString(R.string.app_name));
					events[0] = new String(getString(R.string.notification_sec_text));
					events[1] = "";
				}
				if(FormObject.getInstance().getArtistName().equals("")){
					inboxStyle.setBigContentTitle(FormObject.getInstance().getSongName());
					events[0] = new String(getString(R.string.app_name));
					events[1] = "";
				}
				if(FormObject.getInstance().getArtistName().equals("") && FormObject.getInstance().getArtistName().equals("")){
					inboxStyle.setBigContentTitle(getString(R.string.app_name));
					events[0] = new String(getString(R.string.notification_sec_text));
				}
			}else {
				inboxStyle.setBigContentTitle(getString(R.string.app_name));
				events[0] = new String(getString(R.string.notification_sec_text));
			}
			
			// Moves events into the big view
			for (int i=0; i < events.length; i++)
				inboxStyle.addLine(events[i]);
			
			mBuilder.setStyle(inboxStyle);

			mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
			mNotificationManager.notify(0, mBuilder.build());
		} catch (Exception e) {
		}
	}

	private void stopNotificationOnStatusBar() {
		try {
			// Notification clear in status bar
			mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
			int mId = 0;
			mNotificationManager.cancel(mId);
		} catch (Exception e) {
		}
	}

	// ACT sending SERVICE notifications
	private void myMediaPlayerActivityCallbacks() {
		try {
			br_commonReceiver = new BroadcastReceiver() {
				@Override
				public void onReceive(Context context, Intent intent) {
					int value = MyMediaPlayerServiceNotifyStatus.RESET_N_PREPARE.ordinal(); //6;
					MyMediaPlayerServiceNotifyStatus whichView;

					try {
						value = intent.getIntExtra(MyMediaPlayer.VALUE, value);
						whichView = MyMediaPlayerServiceNotifyStatus.values()[value];
					} catch (Exception e) {
						if(!MyMediaPlayer.getMediaPlayerPauseClicked())
							value = MyMediaPlayerServiceNotifyStatus.RESET_PLAYER.ordinal(); //4;
						else
							value = MyMediaPlayerServiceNotifyStatus.RESET_N_PREPARE.ordinal(); //6;

						whichView = MyMediaPlayerServiceNotifyStatus.values()[value];
					}

					switch (whichView) {
					case GET_AUDIO_FOCUS :
						getMediaPlayerAudioFocus(getApplicationContext());
						break;

					case PREPARE_PLAYER :
						if(MyMediaPlayer.getMediaPlayerPauseClicked()) return;
						try {
							MyMediaPlayer.prepareMediaPlayer();
						} catch (Exception e) {
							MyMediaPlayer.releaseMediaPlayer();
							Intent intent1 = new Intent(MyMediaPlayer.ACT_NOTIFICATION);
							intent1.putExtra(MyMediaPlayer.VALUE, MyMediaPlayerActivityNotifyStatus.ON_ERROR.ordinal());
							sendBroadcast(intent1);
						}
						break;

					case PLAY_PLAYER:
						MyMediaPlayer.playMediaPlayer();
						break;

					case PAUSE_PLAYER:
						MyMediaPlayer.pauseMediaPlayer();
						break;

					case RESET_PLAYER:
						MyMediaPlayer.resetMediaPlayer();
						break;

					case RESET_N_PREPARE:
						try {
							MyMediaPlayer.resetAndPrepareMediaPlayer();
						} catch (Exception e) {
							MyMediaPlayer.releaseMediaPlayer();
							Intent intent1 = new Intent(MyMediaPlayer.ACT_NOTIFICATION);
							intent1.putExtra(MyMediaPlayer.VALUE, MyMediaPlayerActivityNotifyStatus.ON_ERROR.ordinal());
							sendBroadcast(intent1);
						}
						break;

					case RELEASE_PLAYER:
						MyMediaPlayer.releaseMediaPlayer();
						break;

					case START_NOTIFICATION:
						startNotificationOnStatusBar();
						break;

					case STOP_NOTIFICATION:
						stopNotificationOnStatusBar();
						break;

					default:
						MyMediaPlayer.releaseMediaPlayer();
					}
				}
			};
			registerReceiver(br_commonReceiver, new IntentFilter(MyMediaPlayer.SVC_NOTIFICATION)); // ACT sending SERVICE notifications
		} catch (Exception e) {
			MyMediaPlayer.releaseMediaPlayer();
			Intent intent1 = new Intent(MyMediaPlayer.ACT_NOTIFICATION);
			intent1.putExtra(MyMediaPlayer.VALUE, MyMediaPlayerActivityNotifyStatus.ON_ERROR.ordinal());
			sendBroadcast(intent1);
		}
	}
}